package com.ellecity06.common.paging3.adapter

import android.content.Context
import android.util.Log
import android.util.SparseArray
import android.view.ViewGroup
import androidx.annotation.NonNull
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.ellecity06.common.paging3.quick.QuickViewHolder

/**
 * @author ellecity06
 * @time 2023/4/24 10:56
 * @des
 */
open class BaseMultiPagingAdapter<T : Any>(diffCallback: DiffUtil.ItemCallback<T> = itemCallback()) :
    BasePagingAdapter<T, RecyclerView.ViewHolder>(diffCallback) {
    private val typeViewHolders = SparseArray<ItemHolder<T, RecyclerView.ViewHolder>>(1)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val listener = typeViewHolders.get(viewType)
            ?: throw IllegalArgumentException("ViewType: $viewType not found onViewHolderListener，please use addItemType() first!")

        return listener.onCreate(parent.context, parent, viewType)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, item: T?) {
        Log.d("sdadalowqq", "typeViewHolders=${holder.itemViewType}")
        typeViewHolders.get(getItemViewType(position)).onBind(holder, position, item)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, item: T?, payloads: List<Any>) {
        if (payloads.isEmpty()) {
            typeViewHolders.get(getItemViewType(position)).onBind(holder, position, item)
            return
        }
        typeViewHolders.get(getItemViewType(position)).onBind(holder, position, item, payloads)
    }

    /**
     * Call this function to add multiTypeItems.
     * 调用此方法，设置多布局
     * @param type Int
     * @param itemHolder Int
     */
    inline fun <reified V : RecyclerView.ViewHolder> addItemHolder(type: Int, itemHolder: ItemHolder<T, V>) =
        addItemHolder(type, V::class.java, itemHolder)

    fun <V : RecyclerView.ViewHolder> addItemHolder(type: Int, holderClazz: Class<V>, itemHolder: ItemHolder<T, V>) =
        apply {
            typeViewHolders.put(type, itemHolder as ItemHolder<T, RecyclerView.ViewHolder>)
        }

    override fun getItemViewType(item: T?): Int {
        return iItemType?.onItemViewType(item) ?: super.getItemViewType(item)
    }

    private var iItemType: IItemType<T>? = null

    /**
     * 设置 ItemViewType 的监听，根据不同数据类型，返回不同的type值
     *
     * @param listener
     */
    fun onItemViewType(listener: IItemType<T>?) = apply {
        this.iItemType = listener
    }

    override fun onAttachedToRecyclerView(@NonNull recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        val layoutManager = recyclerView.layoutManager
        if (layoutManager is GridLayoutManager) {
            val originalSpanSizeLookup = layoutManager.spanSizeLookup
            layoutManager.spanSizeLookup = object : SpanSizeLookup() {
                override fun getSpanSize(position: Int): Int {
                    return if (isFullSpanItem(getItemViewType(position))) {
                        layoutManager.spanCount
                    } else {
                        originalSpanSizeLookup?.getSpanSize(position) ?: 1
                    }
                }
            }
        }
    }

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
        super.onViewAttachedToWindow(holder)

        typeViewHolders.get(holder.itemViewType)?.onViewAttachedToWindow(holder)
    }

    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
        super.onViewDetachedFromWindow(holder)
        typeViewHolders.get(holder.itemViewType)?.onViewDetachedFromWindow(holder)
    }

    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
        super.onViewRecycled(holder)
        typeViewHolders.get(holder.itemViewType)?.onViewRecycled(holder)
    }

    override fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean {
        return typeViewHolders.get(holder.itemViewType)?.onFailedToRecycleView(holder) ?: super.onFailedToRecycleView(holder)
    }

    override fun isFullSpanItem(itemType: Int): Boolean {
        return super.isFullSpanItem(itemType) ||
                (typeViewHolders.get(itemType)?.isFullSpanItem(itemType) == true)
    }

    @Suppress("UNUSED", "UNCHECKED_CAST", "MemberVisibilityCanBePrivate")
    interface ItemHolder<T : Any, V : RecyclerView.ViewHolder> {
        fun onCreate(context: Context, parent: ViewGroup, viewType: Int): V

        fun onBind(holder: V, position: Int, item: T?)

        fun onBind(holder: V, position: Int, item: T?, payloads: List<Any>) {
            onBind(holder, position, item)
        }

        fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {}

        fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {}

        fun onViewRecycled(holder: RecyclerView.ViewHolder) {}


        fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean = false
        fun isFullSpanItem(itemType: Int): Boolean = false

    }

    fun interface IItemType<T> {
        /**
         * 根据不同数据类型，返回不同的type值
         */
        fun onItemViewType(item: T?): Int
    }
}